package parseur;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import sparqlclient.SparqlInterface;

import database.AppUtilInterface;


public class Parseur {
	
	private AppUtilInterface dao;

	/**
	 * @param dao : interface d'accès à la base de données
	 */
	public Parseur (AppUtilInterface dao) {
		this.dao = dao;
	}
	
	/**
	 * @param paragraphesDirectorypath : chemin du dossier contenant les fichiers xml des balades
	 */
	public void parseParagraphes(String paragraphesDirectorypath) {
		
		SAXParserFactory fabrique = SAXParserFactory.newInstance();
		SAXParser parseur;
		try {
			parseur = fabrique.newSAXParser();
			
			File directoryToScan = new File(paragraphesDirectorypath);
			File[] files = directoryToScan.listFiles();
			
			System.out.println("Début du parsing de tous les documents (" + new Date() + ")");

			// Parse tous les fichiers et remplit toutes les tables à la fin du parsing
			for (File baladeXmlFile : files) {
				if (baladeXmlFile.getAbsolutePath().endsWith(".xml")) {
					DefaultHandler gestionnaire = new ParagraphesHandler(dao, baladeXmlFile.getAbsolutePath().replace('\\', '/'));
					try {
						parseur.parse(baladeXmlFile, gestionnaire);
						
					} catch (SAXException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("Fin du parsing de tous les documents (" + new Date() + ")");
		
		//Mise à jour des tf/idf
		try {
			//Récupérations des valeurs globales nécessaires
			double longueurMoyParagraphe = (double)dao.getLongueurMoyParagraphes();
			
			//Calcul des tf de la table ApparaitDans
			System.out.println("Début du calcul des tf (" + new Date() + ")");
			int nbLignesApparaitDans = dao.getNbLigneApparaitDans();
			HashMap<Integer, Double> tfHashMap = new HashMap<Integer, Double>();
			for (int idLigne = 1; idLigne <= nbLignesApparaitDans; idLigne++) {
				if (idLigne%10000 == 0)
					System.out.println("idLigne "+idLigne);
				//Pour chaque ligne, récupération de la frequence du terme dans le paragraphe et de la longueur du paragraphe associé
				double[] freqEtLong  = dao.getFreqEtLongueur(idLigne);
				double freq = freqEtLong[0];
				double longueur = freqEtLong[1];
				
				// Calcul du tf
				double tf = freq/(0.5+1.5*(longueur/longueurMoyParagraphe)+freq);

				// Ajout du tf à la Hashmap
				tfHashMap.put(idLigne, tf);
			}
			//Rajout des tf dans la table ApparaitDans
			System.out.println("Début de l'ajout des tf (" + new Date() + ")");
			dao.setTfApparaitDans(tfHashMap);
			tfHashMap.clear();
			
			//Rajout des idf dans la table Termes
			System.out.println("Début de l'ajout des idf (" + new Date() + ")");
			dao.setIdfTermes();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("Fin de l'ajout des tf et idf (" + new Date() + ")");
		System.out.println("Fin du traitement (" + new Date() + ")");
	}

	/**
	 * @param queriesFilepath : chemin du fichier xml contenant les requêtes
	 * @param queriesAnswerDirectory : chemin du dossier où écrire les réponses
	 * @param queriesQrelDirectory : chemin du dossier contenant les listes de paragraphes pertinents
	 */
	public void parseQueries(String queriesFilepath, String queriesAnswerDirectory, String queriesQrelDirectory, boolean useSparql, SparqlInterface sparqlAns) {
		
		
		if (!useSparql || (useSparql && sparqlAns!=null)) {
			SAXParserFactory fabrique = SAXParserFactory.newInstance();
			SAXParser parseur;
			try {
				parseur = fabrique.newSAXParser();
				
				File fileToParse = new File(queriesFilepath);
				
				// Parse le fichier et réponds aux requêtes
				DefaultHandler gestionnaire = new QueriesHandler(dao, queriesAnswerDirectory, queriesQrelDirectory, useSparql, sparqlAns);
				try {
					parseur.parse(fileToParse, gestionnaire);
					
				} catch (SAXException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else
			System.out.println("Error : SPARQL client not defined");
	}
}
